﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Net;
using System.Web.Services.Protocols;
using System.Collections;
using SqlMiM.ReportingServices.SqlRs;
using Microsoft.Win32;

namespace SqlMiM.ReportingServices.Core
{
    public class RS
    {
        private static RS current;

        public static RS Current
        {
            get
            {
                if (current == null)
                {
                    current = new RS();
                }

                return current;
            }
        }

        private RS()
        {
        }


        /// <summary>
        /// get the reporting services url
        /// </summary>
        /// <returns></returns>
        public String GetResportingServiceUrl()
        {
            throw new NotImplementedException();

            //if (this.ServerConnection == null)
            //    return null;


            //Object key = Registry.LocalMachine.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS");

            //StringBuilder sb = new StringBuilder();

            //this.Server = new Server(this.ServerConnection);

            ////sb.Append(

            //return sb.ToString();
        }

        /// <summary>
        /// Get registry name for Reporting Services
        /// </summary>
        /// <returns></returns>
        private String GetRegistryReportingServicesName()
        {

            RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS");

            if (key == null) return null;

            return key.GetValue("SQL2008") as String;
        }

        /// <summary>
        /// Get default Reporting Services directory
        /// </summary>
        private String GetReportingServicesDefaultDirectory()
        {
            String rskeyName = this.GetRegistryReportingServicesName();

            if (rskeyName == null) return null;

            String keyName = String.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}\Setup", rskeyName);

            RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName);

            if (key == null) return null;

            String SQLPath = key.GetValue("SQLPath") as String;
            String RSVirtualRootServer = key.GetValue("RSVirtualRootServer") as String;

            if (RSVirtualRootServer == null || SQLPath == null) return null;

            return Path.Combine(SQLPath, RSVirtualRootServer);
        }

        public String GetReportingServicesConfigurationPath()
        {
            String dir = this.GetReportingServicesDefaultDirectory();

            if (dir == null) return null;

            return Path.Combine(dir, "rsreportserver.config");
        }

        public String GetReportingServicesWebServiceUrl()
        {
            String configFile = this.GetReportingServicesConfigurationPath();

            if (configFile == null) return null;

            XmlDocument dc = new XmlDocument();
            dc.Load(configFile);

            var nodeName = dc.SelectNodes("/Configuration/URLReservations/Application[Name='ReportServerWebService']");

            if (nodeName == null) return null;

            String part2 = nodeName[0].SelectSingleNode("VirtualDirectory").InnerText;

            var nodeUrl = dc.SelectNodes("/Configuration/URLReservations/Application[Name='ReportServerWebService']/URLs/URL/UrlString");

            String part1 = nodeUrl[0].InnerText;

            if (part1 == null) return null;

            part1 = part1.Replace("+", Environment.MachineName);

            return String.Format("{0}/{1}/ReportService2005.asmx", part1, part2);
        }


        /// <summary>
        /// Generate directories if required
        /// </summary>
        private void GenerateDirectories(string itemPath)
        {

            int index = itemPath.LastIndexOf(@"\");
            string directoryPath = itemPath;

            if (index > 0)
                directoryPath = itemPath.Remove(index, itemPath.Length - index);

            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }
        }

        /// <summary>
        /// Get Children items
        /// </summary>
        public List<CatalogItem> GetChildrenItems(String webServiceUrl, string path)
        {
            // Reporting Service Instance
            var rs = new ReportingService2005();
            rs.Url = webServiceUrl;

            // Set Credentials
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;


            var items = rs.ListChildren(path, false);

            if (items != null && items.Length > 0)
                return null;

            List<CatalogItem> list = new List<CatalogItem>();

            foreach (CatalogItem item in items)
            {
                list.Add(item);
            }

            return list;
        }

        /// <summary>
        /// For one item, get policies and generate them if necessary
        /// </summary>
        private void GeneratePolicies(ReportingService2005 rs, CatalogItem item, String directoryPath)
        {
            bool inheritParent = true;
            Policy[] policies = rs.GetPolicies(item.Path, out inheritParent);

            if (!inheritParent)
            {
                string policiesFullName = Path.Combine(directoryPath, ToFilePath(item.Path, "pol"));

                PolicyCollection lst = new PolicyCollection(policies);
                StreamWriter stream = new StreamWriter(policiesFullName, false);

                XmlSerializer serializer = new XmlSerializer(typeof(PolicyCollection));

                // Serialize definition
                serializer.Serialize(stream, lst);

                // Close Stream
                stream.Close();

            }

        }

        /// <summary>
        /// For one item, get policies and generate them if necessary
        /// </summary>
        private void GenerateProperties(ReportingService2005 rs, CatalogItem item, String itemFullPath)
        {
            Property[] properties = this.PrepareProperties(item);

            properties = rs.GetProperties(item.Path, properties);


            string propertiesFullName = String.Concat( ToFilePath(itemFullPath, "props"));

            PropertyCollection lst = new PropertyCollection(properties);

            StreamWriter stream = new StreamWriter(propertiesFullName, false);

            XmlSerializer serializer = new XmlSerializer(typeof(PropertyCollection));

            // Serialize definition
            serializer.Serialize(stream, lst);

            // Close Stream
            stream.Close();


        }

        private PropertyCollection GetMinimumProperties()
        {
            PropertyCollection minimumProps = new PropertyCollection();

            Property desc = new Property();
            desc.Name = "Description";
            desc.Value = "";
            minimumProps.Add(desc);

            Property hidden = new Property();
            hidden.Name = "Hidden";
            hidden.Value = "False";
            minimumProps.Add(hidden);


            return minimumProps;

        }

        private PropertyCollection GetProperties(string itemFullPath)
        {
            String propertyFullFileName = String.Format("{0}.props", itemFullPath);
           
            if (!File.Exists(propertyFullFileName))
            {
                return GetMinimumProperties();
            }

            PropertyCollection properties = null;

            TextReader input = new StreamReader(propertyFullFileName);

            XmlReader reader = XmlReader.Create(input);

            XmlSerializer serializer = new XmlSerializer(typeof(PropertyCollection));

            // Serialize definition
            properties = serializer.Deserialize(reader) as PropertyCollection;

            // Close Stream
            reader.Close();
            input.Close();

            if (properties == null || properties.Count == 0)
            {
                return GetMinimumProperties();

            }

            return properties;
        }


        /// <summary>
        /// Create a datasource
        /// </summary>
        public ResultWarning ExportDataSource(ReportingService2005 rs, CatalogItem item, String directoryPath)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {

                string dataSourceFullName = Path.Combine(directoryPath, ToFilePath(item.Path, "rds"));

                this.GenerateDirectories(dataSourceFullName);

                DataSourceDefinition dsDefinition = null;

                dsDefinition = rs.GetDataSourceContents(item.Path);

                if (dsDefinition == null)
                {
                    resultWarning.Type = ResultWarningType.NoDataFound;
                    resultWarning.Message = "DataSource is missing.";
                    return resultWarning;
                }

                this.GeneratePolicies(rs, item, directoryPath);
                this.GenerateProperties(rs, item, dataSourceFullName);

                StreamWriter stream = new StreamWriter(dataSourceFullName, false);

                XmlSerializer serializer = new XmlSerializer(typeof(DataSourceDefinition));

                // Serialize definition
                serializer.Serialize(stream, dsDefinition);

                // Close Stream
                stream.Close();

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("{0} successfuly generated.", ToFilePath(item.Path, "rds"));

            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, ToFilePath(item.Path, "rds"), ex);
            }

            return resultWarning;
        }

        /// <summary>
        /// Create a datasource
        /// </summary>
        public ResultWarning ImportDataSource(ReportingService2005 rs, string physicalDataSourceFullPath, String virtualDataSourceName, String virtualDataSourceParentName)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {
                PropertyCollection allProps = this.GetProperties(physicalDataSourceFullPath);

                var lstProps = from p in allProps
                               where p.Name == "Description" || p.Name == "Hidden"
                               select p;

                Property[] props;

                if (lstProps != null)
                    props = lstProps.ToArray<Property>();
                else
                    props = GetMinimumProperties().ToArray<Property>();

                DataSourceDefinition dsDefinition = null;

                TextReader input = new StreamReader(physicalDataSourceFullPath);

                XmlReader reader = XmlReader.Create(input);

                XmlSerializer serializer = new XmlSerializer(typeof(DataSourceDefinition));

                // Serialize definition
                dsDefinition = serializer.Deserialize(reader) as DataSourceDefinition;

                // Close Stream
                reader.Close();
                input.Close();

                rs.CreateDataSource(virtualDataSourceName, virtualDataSourceParentName, false, dsDefinition, props);

                if (dsDefinition.CredentialRetrieval == CredentialRetrievalEnum.Integrated ||
                    dsDefinition.CredentialRetrieval == CredentialRetrievalEnum.None)
                {
                    resultWarning.Type = ResultWarningType.Completed;
                    resultWarning.Message = String.Format("DataSource {0}/{1} successfuly generated.", virtualDataSourceParentName, virtualDataSourceName);
                }
                else
                {
                    resultWarning.Type = ResultWarningType.DataSourcePasswordMustBeSupplied;
                    resultWarning.Message = String.Format("DataSource {0}/{1} successfuly generated, but you must supply password !", virtualDataSourceParentName, virtualDataSourceName);
                }
            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("DataSource {0}/{1}.", virtualDataSourceParentName, virtualDataSourceName), ex);
            }

            return resultWarning;
        }

        /// <summary>
        /// Import a report
        /// </summary>
        public ResultWarning ImportReport(ReportingService2005 rs, string physicalReportFullPath, String reportName, String virtualDirectoryParentName)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {
                PropertyCollection allProps = this.GetProperties(physicalReportFullPath);

                var lstProps = from p in allProps 
                           where p.Name == "Description" || p.Name =="Hidden"
                           select p;

                Property[] props;

                if (lstProps != null)
                    props = lstProps.ToArray<Property>();
                else
                    props = GetMinimumProperties().ToArray<Property>();

                Byte[] reportDefinition = null;
                System.IO.FileStream stream = System.IO.File.OpenRead(physicalReportFullPath);
                reportDefinition = new Byte[stream.Length];
                stream.Read(reportDefinition, 0, (int)stream.Length);
                stream.Close();

                Warning[] ws = rs.CreateReport(reportName, virtualDirectoryParentName, true, reportDefinition, props);

                

                FileInfo fi = new FileInfo(physicalReportFullPath);

                DataSourceCollection dataSources = null;
                
                // Get all datasources references
                var dataSourcesFiles = fi.Directory.GetFiles(String.Format("{0}.dsrdl", reportName));

                if (dataSourcesFiles != null && dataSourcesFiles.Length > 0)
                {
                    foreach (var dataSourceFile in dataSourcesFiles)
                    {

                        TextReader input = new StreamReader(dataSourceFile.FullName);

                        XmlReader reader = XmlReader.Create(input);

                        XmlSerializer serializer = new XmlSerializer(typeof(DataSourceCollection));

                        // Serialize definition
                        dataSources = serializer.Deserialize(reader) as DataSourceCollection;

                        // Close Stream
                        reader.Close();
                        input.Close();

                    }

                    if (dataSources != null && dataSources.Count > 0)
                        rs.SetItemDataSources(String.Format("{0}/{1}", virtualDirectoryParentName, reportName), dataSources.ToArray());

                }

                resultWarning.Type = ResultWarningType.Completed;
                
                List<Warning> warnings = null;

                if (ws != null && ws.Length > 0)
                {
                    warnings = (from w in ws
                               where w.Code != "rsDataSourceReferenceNotPublished"
                               select w).ToList();

                }

                if (warnings != null && warnings.Count > 0)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine(String.Format("Report {0}/{1} Warnings :", virtualDirectoryParentName, reportName));
                    foreach (var w in warnings)
                    {
                            sb.AppendLine(w.Message);
                    }
                    resultWarning.Message = sb.ToString();
                }
                else
                {
                    resultWarning.Message = String.Format("Report {0}/{1} successfuly generated.", virtualDirectoryParentName, reportName);
                }
            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("Report {0}/{1}.", virtualDirectoryParentName, reportName),  ex);
            }

            return resultWarning;
        }


        /// <summary>
        /// Import a ressource
        /// </summary>
        public ResultWarning ImportRessource(ReportingService2005 rs, string physicalRessourceFullPath, string ressourceName, string virtualDirectoryParentName)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {
                PropertyCollection allProps = this.GetProperties(physicalRessourceFullPath);

                var lstProps = from p in allProps
                               where p.Name == "Description" || p.Name == "Hidden"
                               select p;

                Property[] props;

                if (lstProps != null)
                    props = lstProps.ToArray<Property>();
                else
                    props = GetMinimumProperties().ToArray<Property>();


                var mimeType = (from p in allProps
                               where p.Name == "MimeType"
                               select p).FirstOrDefault();

                String sMimeType = mimeType == null ? String.Empty : mimeType.Value;

                Byte[] ressourceDefinition = null;
                System.IO.FileStream stream = System.IO.File.OpenRead(physicalRessourceFullPath);
                ressourceDefinition = new Byte[stream.Length];
                stream.Read(ressourceDefinition, 0, (int)stream.Length);
                stream.Close();

                rs.CreateResource(ressourceName, virtualDirectoryParentName, true, ressourceDefinition, sMimeType, props);

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("Report {0}/{1} successfuly generated.", virtualDirectoryParentName, ressourceName);
            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("Report {0}/{1}.", virtualDirectoryParentName, ressourceName), ex);
            }

            return resultWarning;
        }

        /// <summary>
        /// Clear a directory (delete all directories and files)
        /// </summary>
        public bool ClearDirectory(String directoryPath)
        {
            try
            {

                DirectoryInfo di = new DirectoryInfo(directoryPath);

                var dirs = di.GetDirectories();
                var files = di.GetFiles();

                foreach (var d in dirs)
                    d.Delete(true);

                foreach (var f in files)
                    f.Delete();

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Create the rs folder directory
        /// </summary>
        public ResultWarning ExportDirectory(ReportingService2005 rs, CatalogItem item, String directoryPath)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {
                string fullDirectoryPath = Path.Combine(directoryPath, this.ToDirectoryPath(item.Path));

                this.GenerateDirectories(fullDirectoryPath);

                if (!Directory.Exists(fullDirectoryPath))
                    Directory.CreateDirectory(fullDirectoryPath);

                this.GeneratePolicies(rs, item, directoryPath);
                this.GenerateProperties(rs, item, fullDirectoryPath);

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("{0} successfuly generated.", this.ToDirectoryPath(item.Path));

            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("{0}.", this.ToDirectoryPath(item.Path)),  ex);
            }

            return resultWarning;
        }

        /// <summary>
        /// Import the rs folder directory
        /// </summary>
        public ResultWarning ImportDirectory(ReportingService2005 rs, String directoryFullPath, String directoryName, String directoryParentName)
        {
            ResultWarning resultWarning = new ResultWarning();

            try
            {
                PropertyCollection allProps = this.GetProperties(directoryFullPath);

                var lstProps = from p in allProps
                               where p.Name == "Description" || p.Name == "Hidden"
                               select p;

                Property[] props;

                if (lstProps != null)
                    props = lstProps.ToArray<Property>();
                else
                    props = GetMinimumProperties().ToArray<Property>();

                rs.CreateFolder(directoryName, directoryParentName, props);

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("Directory {0}{1} successfuly imported.", directoryParentName, directoryName);

            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("Directory {0}{1}.", directoryParentName, directoryName), ex);
            }

            return resultWarning;
        }

        /// <summary>
        /// Create Report
        /// </summary>
        public ResultWarning ExportReport(ReportingService2005 rs, CatalogItem item, String directoryPath)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {

                string reportFullName = Path.Combine(directoryPath, ToFilePath(item.Path, "rdl"));

                this.GenerateDirectories(reportFullName);


                // Get Report
                byte[] reportDefinition = rs.GetReportDefinition(item.Path);

                if (reportDefinition == null)
                {
                    resultWarning.Type = ResultWarningType.NoDataFound;
                    resultWarning.Message = "Report is missing.";
                    return resultWarning;
                }

                ScheduleDefinitionOrReference sdor = null;
                var tmp1 = rs.GetExecutionOptions(item.Path, out sdor);

                var tmp2 = rs.GetItemDataSourcePrompts(item.Path);

                var tmp3 = rs.GetPermissions(item.Path);

                //var tmp4 = rs.GetReportLink(item.Path);

                this.GeneratePolicies(rs, item, directoryPath);
                this.GenerateProperties(rs, item, reportFullName);

                // Get DataSources references and all
                DataSource[] dataSources = rs.GetItemDataSources(item.Path);

                DataSourceCollection dsc = new DataSourceCollection();

                if (dataSources != null && dataSources.Length > 0)
                {
                    foreach (var d in dataSources)
                    {
                        if ((d.Item as InvalidDataSourceReference) == null)
                        {
                            dsc.Add(d);
                        }
                        else
                        {
                            var tmpCol = this.TryParseReportToGetDataSources(reportDefinition);
                            dsc.AddRange(tmpCol);
                        }
                    }
                }
                if (dsc.Count > 0)
                {
                    string dataSourceReferenceFullName = Path.Combine(directoryPath, ToFilePath(item.Path, "dsrdl"));
                    StreamWriter stream = new StreamWriter(dataSourceReferenceFullName, false);
                    XmlSerializer serializer = new XmlSerializer(typeof(DataSourceCollection));
                    // Serialize definition
                    serializer.Serialize(stream, dsc);
                    // Close Stream
                    stream.Close();
                }


                // Open Stream for write
                FileStream streamReport = new FileStream(reportFullName, FileMode.Create);

                // Write Stream
                streamReport.Write(reportDefinition, 0, reportDefinition.Length);

                // Close Stream
                streamReport.Close();

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("{0} successfuly generated.", ToFilePath(item.Path, "rdl"));
            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("{0}.", ToFilePath(item.Path, "rdl")), ex);
            }

            return resultWarning;
        }

        /// <summary>
        /// Create Model
        /// </summary>
        public ResultWarning ExportModel(ReportingService2005 rs, CatalogItem item, String directoryPath)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {

                string modelFullName = Path.Combine(directoryPath, ToFilePath(item.Path, "smdl"));

                this.GenerateDirectories(modelFullName);

                // Get Report
                byte[] modelDefinition = rs.GetModelDefinition(item.Path);

                if (modelDefinition == null)
                {
                    resultWarning.Type = ResultWarningType.NoDataFound;
                    resultWarning.Message = "Model is missing.";
                    return resultWarning;
                }

                this.GeneratePolicies(rs, item, directoryPath);
                this.GenerateProperties(rs, item, modelFullName);

                FileStream stream = new FileStream(modelFullName, FileMode.Create);

                // Write Stream
                stream.Write(modelDefinition, 0, modelDefinition.Length);

                // Close Stream
                stream.Close();

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("{0} successfuly generated.", ToFilePath(item.Path, "smdl"));
            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning,String.Format("{0}.", ToFilePath(item.Path, "smdl")), ex);
            }

            return resultWarning;
        }


        /// <summary>
        /// IF we have an InvalidDataSourceReference when Getting DataSource, we try to get inline datasources
        /// </summary>
        public DataSourceCollection TryParseReportToGetDataSources(byte[] reportDefinition)
        {
            XmlDocument doc = new XmlDocument();
            MemoryStream memoryStream = new MemoryStream(reportDefinition);
            doc.Load(memoryStream);
            memoryStream.Close();

            DataSourceCollection dataSourceCollection = new DataSourceCollection();

            // Récupération des DataSources incluses dans le document XML
            XmlNodeList listXmlDataSources = doc.GetElementsByTagName("DataSource");

            ArrayList lstDataSources = new ArrayList();

            // Foreahc DataSource
            foreach (XmlNode xmlDs in listXmlDataSources)
            {
                // Get Name
                String dataSourceName = xmlDs.Attributes["Name"].Value;


                foreach (XmlNode node in xmlDs.ChildNodes)
                {
                    if (node.Name == "DataSourceReference")
                    {
                        DataSource newDS = new DataSource();
                        DataSourceReference dsRef = new DataSourceReference();
                        dsRef.Reference = node.InnerText;
                        newDS.Item = dsRef;
                        newDS.Name = dataSourceName;

                        dataSourceCollection.Add(newDS);
                    }
                }



            }
            return dataSourceCollection;

        }


        /// <summary>
        /// Create Ressource
        /// </summary>
        public ResultWarning ExportRessource(ReportingService2005 rs, CatalogItem item, String directoryPath)
        {
            ResultWarning resultWarning = new ResultWarning();
            try
            {

                string ressourceFullName = Path.Combine(directoryPath, ToFilePath(item.Path, "resx"));

                this.GenerateDirectories(ressourceFullName);

                // Get Ressource
                String mimeType;

                byte[] ressourceArray = rs.GetResourceContents(item.Path, out mimeType);

                if (ressourceArray == null)
                {
                    resultWarning.Type = ResultWarningType.NoDataFound;
                    resultWarning.Message = "Ressource is missing.";
                    return resultWarning;
                }

                this.GeneratePolicies(rs, item, directoryPath);
                this.GenerateProperties(rs, item, ressourceFullName);

                FileStream stream = new FileStream(ressourceFullName, FileMode.Create);

                // Write Stream
                stream.Write(ressourceArray, 0, ressourceArray.Length);

                // Close Stream
                stream.Close();

                resultWarning.Type = ResultWarningType.Completed;
                resultWarning.Message = String.Format("{0} successfuly generated.", ToFilePath(item.Path, "resx"));
            }
            catch (Exception ex)
            {
                this.GenerateErrorData(resultWarning, String.Format("{0}.", ToFilePath(item.Path, "resx")), ex);
            }

            return resultWarning;
        }


        private string ToFilePath(string path, string extension)
        {
            string str = path.TrimStart(new char[] { '/' }).Replace("/", @"\");

            if (str.EndsWith(@"\"))
                str = str.Remove(str.LastIndexOf(@"\"), 1);


            return String.Format("{0}.{1}", str, extension);
        }

        private string ToDirectoryPath(string path)
        {
            string str = path.TrimStart(new char[] { '/' }).Replace("/", @"\");
            if (!str.EndsWith(@"\"))
            {
                str = str + @"\";
            }
            return str;
        }

        private void GenerateErrorData(ResultWarning warning, String title, Exception ex)
        {
            warning.Exception = ex;
            warning.Message = title + Environment.NewLine + ex.Message;

            if (ex is IOException)
            {
                warning.Type = ResultWarningType.Exception;
            }
            else if (ex is WebException)
            {
                warning.Type = ResultWarningType.WebException;
            }
            else if (ex is SoapException)
            {
                SoapException soapException = ex as SoapException;

                if (soapException.Detail["ErrorCode"].InnerText == "rsItemAlreadyExists")
                {
                    warning.Type = ResultWarningType.ItemAlreadyExists;
                    warning.Message = soapException.Detail["Message"].InnerText;
                }
                else
                {
                    warning.Type = ResultWarningType.SoapException;
                }
            }
            else if (ex is Exception)
            {
                warning.Type = ResultWarningType.Exception;
            }
        }

        private Property[] PrepareProperties(CatalogItem item)
        {
            ArrayList propArray = new ArrayList();

            propArray.Add(new Property() { Name = "CreatedBy" });
            propArray.Add(new Property() { Name = "CreationDate" });
            propArray.Add(new Property() { Name = "Description" });
            propArray.Add(new Property() { Name = "Hidden" });
            propArray.Add(new Property() { Name = "ID" });
            propArray.Add(new Property() { Name = "ModifiedBy" });
            propArray.Add(new Property() { Name = "ModifiedDate" });
            propArray.Add(new Property() { Name = "Name" });
            propArray.Add(new Property() { Name = "Path" });
            propArray.Add(new Property() { Name = "Size" });
            propArray.Add(new Property() { Name = "Type" });
            propArray.Add(new Property() { Name = "VirtualPath" });

            if (item.Type == ItemTypeEnum.Report)
            {
                propArray.Add(new Property() { Name = "Language" });
                propArray.Add(new Property() { Name = "ReportProcessingTimeout" });
                propArray.Add(new Property() { Name = "ExecutionDate" });
                propArray.Add(new Property() { Name = "CanRunUnattended" });
                propArray.Add(new Property() { Name = "HasParameterDefaultValues" });
                propArray.Add(new Property() { Name = "HasDataSourceCredentials" });
                propArray.Add(new Property() { Name = "IsSnapshotExecution" });
                propArray.Add(new Property() { Name = "HasScheduleReadyDataSources" });
            }
            else if (item.Type == ItemTypeEnum.Resource)
            {
                propArray.Add(new Property() { Name = "MimeType" });
            }
            else if (item.Type == ItemTypeEnum.Folder)
            {
                propArray.Add(new Property() { Name = "Reserved" });
            }

            return (Property[])propArray.ToArray(typeof(Property));
        }


    }

}
